﻿using UnityEngine;
using System.Collections.Generic;
using System.Text;

public class ActionProcessor : MonoBehaviour {
    public VisualSideBoardManager visualBoard;
    public LogicSideBoardManager logicBoard;

    public int boardHeight;
    public int boardWidth;

    public Material selectMat, unselectMat;

    public GameObject currentSelectedSpace;
    public bool currentSelectedOccupied = false;

    public int boardX, boardY;

    bool main = true;
    public bool addition;

    Vector2 sP = new Vector2(0,0);//scroll position

    private CityManager cityManager;

	// Use this for initialization
	void Start () {

        cityManager = GameObject.FindGameObjectWithTag("City").GetComponent<CityManager>();


	}
	
	// Update is called once per frame
	void Update () {
        MouseCheck();
	}

    void OnGUI()
    {



        ///////////Debug////////////
        if (currentSelectedSpace != null)
        {

            Dictionary<string, Building> buildingsByName = cityManager.GetBuildings();

           
            GUILayout.BeginArea(new Rect(Screen.width / 12, 40, Screen.width / 6, Screen.width / 4));
            if (GUILayout.Button("None"))
            {
                ProcessIncomingInformation(boardX, boardY, buildingsByName["None"].type, Building.Orientation.East);
            }
            sP = GUILayout.BeginScrollView(sP);

            List<string> buildingNames = new List<string>();
            foreach (string key in buildingsByName.Keys) buildingNames.Add(key);
            buildingNames.Sort();

            foreach (string key in buildingNames)
            {
                if (key != "None")
                {
                    if (GUILayout.Button(key))
                    {
                        ProcessIncomingInformation(boardX, boardY, buildingsByName[key].type, buildingsByName[key].orientation);

                    }
                }
            }

            GUILayout.EndScrollView();
            GUILayout.EndArea();
            
        }

    }

   ///////////////////////////Debug//////////////////////

    void MouseCheck()
    {
        if (Input.GetButtonDown("Fire1"))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray,out hit))
            {
                if (hit.transform.tag == "gridSpace")
                {
                    if (hit.transform.gameObject == currentSelectedSpace)
                    {
                        hit.transform.renderer.material = unselectMat;
                        currentSelectedSpace = null;
                    }
                    else
                    {
                        if(currentSelectedSpace!=null)
                        {
                            currentSelectedSpace.transform.renderer.material = unselectMat;
                        }
                        currentSelectedSpace= hit.transform.gameObject;
                        hit.transform.renderer.material = selectMat;

                        string[] logicalCoordinates = currentSelectedSpace.name.Split('-');
                        print(currentSelectedSpace.name);
                        //boardX = currentSelectedSpace.name[1] -'0';
                        //boardY = currentSelectedSpace.name[4] -'0';
                        boardX = int.Parse(logicalCoordinates[0]);
                        boardY = int.Parse(logicalCoordinates[1]);
                        print(string.Format("click to board {0}, {1}", boardX, boardY));
                    }
                }
            }

        }
    }

    void ProcessIncomingInformation(int x, int y, Building.BuildingType buildingType, Building.Orientation orientation)
    {

        // TODO: Validate the building type against the buildings in the city.
        // New rule: You can only place if the whole target area is empty.
        Building buildingToPlace = new Building(buildingType, orientation);
        List<Vector2> placementSpots = new List<Vector2>();
        placementSpots.Add(new Vector2(x, y));
        switch (buildingToPlace.size)
        {
            case Building.BuildingSize.Size1x2:
                switch (orientation)
                {
                    case Building.Orientation.East:
                        placementSpots.Add(new Vector2(x + 1, y));
                        break;
                    case Building.Orientation.West:
                        placementSpots.Add(new Vector2(x - 1, y));
                        break;
                    case Building.Orientation.North:
                        placementSpots.Add(new Vector2(x, y + 1));
                        break;
                    case Building.Orientation.South:
                        placementSpots.Add(new Vector2(x, y - 1));
                        break;
                }
                break;
            case Building.BuildingSize.Size2x2:
                switch (orientation)
                {
                    case Building.Orientation.East:
                        placementSpots.Add(new Vector2(x + 1, y));
                        placementSpots.Add(new Vector2(x, y - 1));
                        placementSpots.Add(new Vector2(x + 1, y - 1));
                        break;
                    case Building.Orientation.West:
                        placementSpots.Add(new Vector2(x - 1, y));
                        placementSpots.Add(new Vector2(x, y + 1));
                        placementSpots.Add(new Vector2(x - 1, y + 1));
                        break;
                    case Building.Orientation.North:
                        placementSpots.Add(new Vector2(x, y + 1));
                        placementSpots.Add(new Vector2(x + 1, y));
                        placementSpots.Add(new Vector2(x + 1, y + 1));
                        break;
                    case Building.Orientation.South:
                        placementSpots.Add(new Vector2(x, y - 1));
                        placementSpots.Add(new Vector2(x - 1, y));
                        placementSpots.Add(new Vector2(x - 1, y - 1));
                        break;
                }
                break;
        }

        List<Vector2> occupiedLocations = new List<Vector2>();
        foreach (Vector2 placementSpot in placementSpots)
        {
            // TODO: Add occupied locations in placementSpots to occupiedLocations
            if (!cityManager.ValidatePlacementAvailable((int)placementSpot.x, (int)placementSpot.y))
                occupiedLocations.Add(placementSpot);
        }
        if (occupiedLocations.Count > 0)
        {
            StringBuilder validationErrorBuilder = new StringBuilder();
            validationErrorBuilder.AppendFormat("Cannot place building of type {0} at ({1}, {2}) with orientation {3}\n", buildingType, x, y, orientation);
            foreach (Vector2 occupiedLocation in occupiedLocations)
            {
                validationErrorBuilder.AppendFormat("Position {0} occupied or off the board\n", occupiedLocation);
            }
            print(validationErrorBuilder.ToString());
            return;
        }


        if (buildingType == Building.BuildingType.Empty)
        {
            cityManager.DestroyBuilding(x, y);
        }
        else
        {
            // TODO: Add orientation handling instead of defaulting to East
            cityManager.ReplaceBuilding(x, y, new Building(buildingType, orientation));
        }


    }
  

}
